package utils

// 导入必要的包
import (
	"Lunar-Astral-API/local_server/config" // 项目配置相关包
	"fmt"                                  // 导入fmt包，用于格式化输出
	"net"                                  // 导入net包，用于网络操作
	"strings"                              // 导入strings包，用于字符串操作
)

// GetLocalIP 获取本地可用的IP地址。
// 优先返回局域网IP地址（10.x.x.x、172.16.x.x 或 192.168.x.x），若未找到则返回其他非回环IPv4地址。
// 若未找到可用的IP地址，则返回错误。
// 返回值：
// - string：找到的本地IP地址
// - error：操作过程中发生的错误，若未找到可用IP也会返回错误
func GetLocalIP() (string, error) {
	// 获取系统所有网络接口的地址
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		// 获取地址列表失败，返回错误
		return "", err
	}
	// 第一次遍历，优先查找局域网IP地址
	for _, addr := range addrs {
		// 尝试将地址转换为 net.IPNet 类型
		ipNet, ok := addr.(*net.IPNet)
		// 检查是否转换成功、不是回环地址且是IPv4地址
		if ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil {
			// 提取IP地址字符串
			ip := ipNet.IP.String()
			// 检查是否为局域网IP地址
			if strings.HasPrefix(ip, "10.") || strings.HasPrefix(ip, "172.16.") || strings.HasPrefix(ip, "192.168.") {
				// 找到局域网IP，返回该地址
				return ip, nil
			}
		}
	}
	// 第二次遍历，查找其他非回环IPv4地址
	for _, addr := range addrs {
		// 尝试将地址转换为 net.IPNet 类型
		ipNet, ok := addr.(*net.IPNet)
		// 检查是否转换成功、不是回环地址且是IPv4地址
		if ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil {
			// 找到可用的非回环IPv4地址，返回该地址
			return ipNet.IP.String(), nil
		}
	}
	// 未找到可用的IP地址，返回错误信息
	return "", fmt.Errorf("Web服务[ERROR] -> 未找到可用的IP地址")
}

// ClientUrl 根据配置生成客户端访问的URL地址。
// 如果配置中 UseLocalAreaNetwork 为 true，则使用传入的IP地址生成URL；
// 否则使用 localhost 生成URL。
// 参数 ip 为本地可用的IP地址。
// 返回生成的客户端访问URL字符串。
func ClientUrl(ip string) string {
	// 先默认使用 localhost 生成URL
	url := fmt.Sprintf("http://localhost:%d", *config.SystemUrlPort)
	// 若配置中指定使用局域网，则使用传入的IP地址生成URL
	if *config.UseLocalNetwork {
		url = fmt.Sprintf("http://%s:%d", ip, *config.SystemUrlPort)
	}
	return url
}
